package com.wnxy.sddfp.trade.service.impl;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wnxy.sddfp.client.bank.TradeLogApi;
import com.wnxy.sddfp.client.system.UserApi;
import com.wnxy.sddfp.common.constant.UserConstant;
import com.wnxy.sddfp.common.enums.PayTypeEnums;
import com.wnxy.sddfp.common.exception.Assert;
import com.wnxy.sddfp.common.model.dto.trade.BorrowRecordDTO;
import com.wnxy.sddfp.common.model.page.Pages;
import com.wnxy.sddfp.common.model.query.BorrowQuery;
import com.wnxy.sddfp.common.model.vo.trade.BorrowRecordVo;
import com.wnxy.sddfp.common.model.vo.user.TokenVo;
import com.wnxy.sddfp.common.model.vo.user.UserInfoVo;
import com.wnxy.sddfp.common.result.Result;
import com.wnxy.sddfp.common.result.enums.impl.ResultCode;
import com.wnxy.sddfp.common.util.IdGenerator;
import com.wnxy.sddfp.common.util.TokenUtils;
import com.wnxy.sddfp.trade.entity.BorrowRecord;
import com.wnxy.sddfp.trade.mapper.BorrowRecordMapper;
import com.wnxy.sddfp.trade.service.IBorrowRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 * 借款信息表 服务实现类
 * </p>
 *
 * @author Jet
 * @since 2023-05-08
 */
@Service
public class BorrowRecordServiceImpl extends ServiceImpl<BorrowRecordMapper, BorrowRecord> implements IBorrowRecordService {

    @Autowired
    private UserApi userApi;
    @Autowired
    private TradeLogApi tradeLogApi;

    @Override
    public void addBorrowRecord(BorrowRecordDTO borrowRecordDTO) {
        // 从token请求头中获取用户信息
        TokenVo tokenVo = TokenUtils.getTokenVo();
        // 封装借款记录对象
        BorrowRecord borrowRecord = new BorrowRecord();
        borrowRecord.setUserId(Long.parseLong(tokenVo.getId()));
        borrowRecord.setPeriod(borrowRecordDTO.getPeriod());
        borrowRecord.setAmount(borrowRecordDTO.getAmount());

        borrowRecord.setBorrowRecordNo(IdGenerator.generator(UserConstant.BORROW_CODE_PREFIX));
        borrowRecord.setBorrowStatus("NEW");
        borrowRecord.setRepaymentWay(PayTypeEnums.DEBJ.getCode());
        borrowRecord.setStatus(false);

        borrowRecord.setInvestRate(new BigDecimal("10"));
        borrowRecord.setBorrowerRate(new BigDecimal("10"));
        borrowRecord.setCommissionRate(new BigDecimal("10"));

        // 查询获取用户信息：用户编码、名称、身份证
        Result<UserInfoVo> result = userApi.queryUserById(borrowRecord.getUserId());
        Assert.error(result.getCode()!= ResultCode.SUCCESS.getCode(),ResultCode.DATA_IS_WRONG);

        UserInfoVo userInfoVo = result.getData();
        borrowRecord.setUserCode(userInfoVo.getUserCode());
        borrowRecord.setName(this.convertName(userInfoVo));

        borrowRecord.setCreateDate(new Date());
        borrowRecord.setModifyDate(new Date());
        borrowRecord.setDescription("无");

        this.save(borrowRecord);
    }

    private String convertName(UserInfoVo userInfoVo) {
        // 根据用户id查询
        long count = this.count(Wrappers.lambdaQuery(BorrowRecord.class).eq(BorrowRecord::getUserCode, userInfoVo.getUserCode()));

        // 张三先生/女士的第一次借款 身份证号码第17位是性别
        Integer num = Integer.parseInt( userInfoVo.getIdentityCode().substring(16,17));
        StringBuffer sb = new StringBuffer();
        sb.append(userInfoVo.getUserName())
                .append(num % 2 == 0 ? "女士" : "先生")
                .append("第" + (count+1))
                .append("次借款");
        return sb.toString();
    }

    @Override
    public Pages<BorrowRecordVo> queryBorrowRecord(
            BorrowQuery borrowQuery, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<BorrowRecord> wrapper = Wrappers.lambdaQuery(BorrowRecord.class);
        if (StringUtils.hasText(borrowQuery.getName())) {
            wrapper.like(BorrowRecord::getName,borrowQuery.getName());
        }
        if (borrowQuery.getStartPeriod() != null) {
            wrapper.ge(BorrowRecord::getPeriod,borrowQuery.getStartPeriod());
        }
        if (borrowQuery.getEndPeriod() != null) {
            wrapper.le(BorrowRecord::getPeriod,borrowQuery.getEndPeriod());
        }
        if (StringUtils.hasText(borrowQuery.getBorrowStatus())) {
            wrapper.eq(BorrowRecord::getBorrowStatus,borrowQuery.getBorrowStatus());
        }
        // 分页查询
        Page<BorrowRecord> page = this.page(new Page<>(pageNum, pageSize), wrapper);
        // 获取分页数据
        List<BorrowRecord> records = page.getRecords();
        // 转换：BorrowRecord-->BorrowRecordVo
        List<BorrowRecordVo> recordVoList = records.stream().map(
                borrowRecord -> BeanUtil.copyProperties(borrowRecord, BorrowRecordVo.class))
                .collect(Collectors.toList());

        return new Pages<>(pageNum,pageSize,page.getTotal(), recordVoList);
    }

    @Override
    public void verifyStatus(Long borrowRecordId, String status) {
        //1. 根据借款记录id查询
        BorrowRecord borrowRecord = this.getById(borrowRecordId);

        //2. 封装BorrowRecordVo, 作为访问托管代理的请求参数
        BorrowRecordVo borrowRecordVo =
                BeanUtil.copyProperties(borrowRecord, BorrowRecordVo.class);

        //3. 生成请求流水号（流水号已经有，就不用再重新生成）
        if (StringUtils.isEmpty(borrowRecord.getReqCode())) {
            //3.1 生成借款审核请求流水号
            String reqCode = IdGenerator.generator(UserConstant.BORROW_CODE_PREFIX);
            //3.2 设置到vo中
            borrowRecordVo.setReqCode(reqCode);
            //3.3 修改数据库
            this.update(Wrappers.lambdaUpdate(BorrowRecord.class)
                    .set(BorrowRecord::getReqCode,reqCode)
                    .eq(BorrowRecord::getId,borrowRecord.getId()));
        }

        //TODO 4. 调用托管代理系统，同步借款信息
        Result result = tradeLogApi.syncBorrowRecord(borrowRecordVo);

        //5. 数据同步成功，审核通过，修改BorrowRecord表中status状态为1
        if (result.getCode() == ResultCode.SUCCESS.getCode()) {
            this.update(Wrappers.lambdaUpdate(BorrowRecord.class)
                    .set(BorrowRecord::getStatus,status)
                    .eq(BorrowRecord::getId,borrowRecord.getId()));
        }
    }


}
